﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Runtime.InteropServices;
using System.Diagnostics;
using AOC19NET.Classes;
using AOC19NET.Controls;

namespace AOC19NET {
	/// <summary>
	/// GMail info class.
	/// </summary>
	class GMailPage {
		/*-------------------------------------------------------------------------*/
		/* DEFINITIONS															   */
		/*-------------------------------------------------------------------------*/
		#region DEFINITIONS
		#endregion

		/*-------------------------------------------------------------------------*/
		/* MEMBERS																   */
		/*-------------------------------------------------------------------------*/
		#region MEMBERS
		/// <summary>
		/// Custom control containing all the elements on the LCD screen
		/// </summary>
		public GMailControl m_MainControl;

		/// <summary>
		/// This object will allow us to read from GMail accounts.
		/// </summary>
		private RC.Gmail.GmailAtomFeed m_GMailFeed;

		/// <summary>
		/// Last time the GMail feed was updated.
		/// </summary>
		private DateTime m_LastUpdate;

		/// <summary>
		/// Keep track of the mail in the list that has the current focus.
		/// </summary>
		private int m_iFocusedMail;

		/// <summary>
		/// Keep the base color to apply it at each update.
		/// </summary>
		private Color m_BaseColor;
		#endregion

		/*-------------------------------------------------------------------------*/
		/* METHODS																   */
		/*-------------------------------------------------------------------------*/
		#region METHODS
		/// <summary>
		/// Constructor of the class: sets all the members to its default values.
		/// </summary>
		public GMailPage() {
			// Initialize custom controls
			m_MainControl = new GMailControl();
			m_iFocusedMail = 0;
			m_BaseColor = Colors.LightGray;
		}

		/// <summary>
		/// Actions to do once at the beginning.
		/// </summary>
		public void Init() {
			// Create a new GMail feed with the username and password from the app settings.
			m_GMailFeed = new RC.Gmail.GmailAtomFeed(Properties.Settings.Default.GMailUsername, Properties.Settings.Default.GMailPassword);

			// To get the new inbox messages set this to string.Empty
			// See other default labels at http://www.mydigitallife.info/2007/11/21/list-of-hidden-gmail-pre-definied-labels/
			m_GMailFeed.FeedLabel = String.Empty;

			// First update
			CheckGMail();
			UpdateList();
		}

		/// <summary>
		/// Actions to do during the update process.
		/// To be called periodically.
		/// </summary>
		public void Run() {
			// 1. Update GMail feed if the interval in the app settings has passed.
			if((DateTime.Now - m_LastUpdate).TotalSeconds > Properties.Settings.Default.GMailUpdateFrequency) {
				// Update Settings
				UpdateSettings();

				// Check feed
				CheckGMail();

				// Update the list
				UpdateList();
			}
		}

		/// <summary>
		/// Actions to do during the render process, typically update the graphics.
		/// To be called periodically.
		/// </summary>
		public void Render() {
			
		}

		/// <summary>
		/// Update the gmail feed. To be called periodically, but not too often!
		/// </summary>
		private void CheckGMail() {
			m_LastUpdate = DateTime.Now;

			// 1. Try to connect to GMail account
			bool bConnectionSuccessful = true;
			try {
				m_GMailFeed.GetFeed();
			} catch(Exception e) {
				Console.WriteLine();
				Console.WriteLine("ERROR: Couldn't obtain the GMail feed");
				Console.WriteLine(e);
				Console.WriteLine();
				bConnectionSuccessful = false;
			}

			if(bConnectionSuccessful) {
				// 2. How many new messages do we have?
				int iNewMessages = m_GMailFeed.FeedEntries.Count;
				if(iNewMessages == 0) {
					m_MainControl.m_TextBoxMessages.Text = "No unread messages";
				} else {
					m_MainControl.m_TextBoxMessages.Text = String.Format("You have {0} new messages!", iNewMessages);
				}
				m_MainControl.m_ErrorBox.Text = "";
			} else {
				// Connection error: Show error message
				m_MainControl.m_MessageList.Items.Clear();
				m_MainControl.m_TextBoxMessages.Text = "ERROR";
				m_MainControl.m_ErrorBox.Text = "An error occurred while connecting to GMail. Please, check your settings.";
			}
		}

		/// <summary>
		/// Gets the settings from the application configuration.
		/// </summary>
		private void UpdateSettings() {
			m_GMailFeed.GmailUserName = Properties.Settings.Default.GMailUsername;
			m_GMailFeed.GmailPassword = Properties.Settings.Default.GMailPassword;
		}

		/// <summary>
		/// Returns the number of unread messages in the current feed.
		/// </summary>
		/// <returns>Number of unread messages in the current feed. 0 if the feed is not valid.</returns>
		public int GetUnread() {
			return m_GMailFeed.FeedEntries.Count;
		}

		/// <summary>
		/// Updates the mail list in the interface.
		/// </summary>
		private void UpdateList() {
			// Clear the mail list and add all the new mails
			m_MainControl.m_MessageList.Items.Clear();
			foreach(RC.Gmail.GmailAtomFeed.AtomFeedEntry NewMessage in m_GMailFeed.FeedEntries) {
				// 1. Create a new EmailBox control
				Controls.EmailBox NewEmailBox = new Controls.EmailBox();
				NewEmailBox.m_ReceivedTime = NewMessage.Received;
				NewEmailBox.m_sFrom = NewMessage.FromName;
				NewEmailBox.m_sSubject = NewMessage.Subject;
				NewEmailBox.m_sBrief = NewMessage.Summary;

				// 2. Create a new ListBoxItem
				System.Windows.Controls.ListBoxItem NewItem = new System.Windows.Controls.ListBoxItem();
				NewItem.Content = NewEmailBox;
				NewItem.Padding = new Thickness(0, 3, 0, 0);

				// 3. Add the ListBoxItem to the list
				m_MainControl.m_MessageList.Items.Add(NewItem);
			}

			// Focus to the selected mail
			Scroll(0);

			// Apply color scheme
			ChangeColorScheme(m_BaseColor);
		}

		/// <summary>
		/// Scrolls the mails list up or down, if possible.
		/// </summary>
		/// <param name="_iDirection">The scrolling direction: 1 for down, -1 for up, 0 for refresh.</param>
		public void Scroll(int _iDirection) {
			// If there are no mails, return.
			int iNumMails = m_MainControl.m_MessageList.Items.Count;
			if(iNumMails == 0) {
				return;
			}

			// 1. Store the current focused item and increase the index
			int iLastFocused = m_iFocusedMail;
			m_iFocusedMail += _iDirection;

			// 2. Clamp the index between 0 and number of mails
			if(m_iFocusedMail >= iNumMails) {
				m_iFocusedMail = iNumMails - 1;
			} else if(m_iFocusedMail < 0) {
				m_iFocusedMail = 0;
			}

			// 3. Focus the selected mail
			m_MainControl.m_MessageList.ScrollIntoView(m_MainControl.m_MessageList.Items[m_iFocusedMail]);

			// 4. If changed OR refresh, update the backgrounds
			if((iLastFocused != m_iFocusedMail) || (_iDirection == 0)) {
				System.Windows.Controls.ListBoxItem LastItem = (System.Windows.Controls.ListBoxItem)m_MainControl.m_MessageList.Items[iLastFocused];
				System.Windows.Controls.ListBoxItem NewItem = (System.Windows.Controls.ListBoxItem)m_MainControl.m_MessageList.Items[m_iFocusedMail];

				LastItem.Background = Brushes.Transparent;
				NewItem.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0xDD, 0xEE, 0xFF));
				NewItem.Background = new SolidColorBrush(ColorHelper.Tint(m_BaseColor, 0.9f));
			}
		}

		/// <summary>
		/// Changes the current color scheme.
		/// </summary>
		/// <param name="_NewBaseColor">The new base color. Each element color will be a tint of this one.</param>
		public void ChangeColorScheme(Color _NewBaseColor) {
			// Header
			m_MainControl.m_Grid.Background = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.55f));
			m_MainControl.m_TextBoxMessages.Foreground = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.25f));

			// Message List
			for(int i = 0; i < m_MainControl.m_MessageList.Items.Count; i++) {
				System.Windows.Controls.ListBoxItem CurrentItem = (System.Windows.Controls.ListBoxItem)m_MainControl.m_MessageList.Items[i];
				Controls.EmailBox CurrentEmail = (Controls.EmailBox)CurrentItem.Content;

				// Backgrounds
				CurrentEmail.m_FillDateTime.Fill = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.6f));
				CurrentEmail.m_FillNameSubject.Fill = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.8f));

				// Lines
				CurrentEmail.m_Line1.Fill = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.6f));
				CurrentEmail.m_Line2.Fill = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.6f));
				CurrentEmail.m_Line3.Fill = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.6f));

				// Texts
				CurrentEmail.m_LabelDate.Foreground = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.3f));
				CurrentEmail.m_LabelHour.Foreground = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.3f));
				CurrentEmail.m_TextBlockMessage.Foreground = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.7f));

				// If focused item, change background
				if(i == m_iFocusedMail) {
					CurrentItem.Background = new SolidColorBrush(ColorHelper.Tint(_NewBaseColor, 0.9f));
				}
			}

			// Store base color
			m_BaseColor = _NewBaseColor;
		}

		/// <summary>
		/// Starts the default internet browser with the GMail home page.
		/// </summary>
		public void StartBrowser() {
			try {
				System.Diagnostics.Process.Start("http://mail.google.com");
			} catch(Exception e) {
				Console.WriteLine(e);
			}
		}
		#endregion
	}
}
